<?php

namespace api;

use app\api\service\OilXiaojuService;

/**
 * 小桔加油 相关接口文档地址 https://open-epower.xiaojukeji.com/oil.html#/oil-api-h5/unicomFile/73.
 */
class Xiaoju
{
    public $config;
    public $openChannel = 1;

    public function __construct($config = null)
    {
        if (!$config) {
            $this->config = config('xiaoju');
        } else {
            $this->config = $config;
        }
        if (env('APP_DEBUG')) {
            //$this->config['app_key'] .= 'test';  // 调试用 test
        }
    }

    public function curl($url, $data = [])
    {
        // 默认全局参数处理
        //if ('queryToken' != $url) {
        $data = $this->defaultQueryData($data);
        //}

        // 加密 和签名
        $dataInit = '';
        include_once root_path('extend/api').'/AES.php';
        $data = $this->encrypt($data, $dataInit);
        $SSL = 'https://' == substr($this->config['api_address'].$url, 0, 8) ? true : false;

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->config['api_address'].$url);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 28);
        if ($SSL) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 检查证书中是否设置域名
        }
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Expect:']); //避免data数据过长问题
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);
        if ('queryToken' != $url) {
            $tokenInfo = invoke(OilXiaojuService::class)->queryToken();

            if ($tokenInfo['code']) {
                return ['code' => $tokenInfo['code'], 'msg' => '获取token失败'];
            }
            $headers[] = 'Content-Type:application/json; charset=utf-8';
            $headers[] = 'Authorization: Bearer '.$tokenInfo['data']['access_token'];
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        } else {
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json; charset=utf-8']);
        }
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        $retStr = curl_exec($ch);
        //$request_header = curl_getinfo($ch, CURLINFO_HEADER_OUT);
        //print_r($request_header);
        curl_close($ch);

        $ret = json_decode($retStr, true);
        if (0 != $ret['code']) {
            doLog('Xiaoju->url,'.__LINE__.',请求日志,url='.$url.',data='.$dataInit.',失败返回值'.$retStr);

            return ['code' => $ret['code'], 'msg' => $ret['msg']];
        }

        $dataInfo = $this->decrypt($ret); //json_decode(AES::decrypt(json_encode($ret['data']), $this->config['data_secret']), true);
        doLog('Xiaoju->url,'.__LINE__.',请求日志,url='.$url.',data='.$dataInit.',解析data返回值'.json_encode($dataInfo, JSON_UNESCAPED_UNICODE));

        return ['code' => $ret['code'], 'data' => $dataInfo];
    }

    /**
     * 解析回调参数.
     */
    public function decrypt($ret)
    {
        return json_decode(AES::decrypt(json_encode($ret['data']), $this->config['data_secret']), true);
    }

    /**
     * 加密.
     */
    public function encrypt($data, &$dataInit = '', $withTimeStamp = 1)
    {
        $dataInit = json_encode($data, JSON_UNESCAPED_UNICODE);
        $data = AES::encrypt(json_encode($data), $this->config['data_secret']);

        if (1 == $withTimeStamp) {
            $timeStamp = date('YmdHis');
            $addData = [
                'appKey' => $this->config['app_key'],
                'data' => $data,
                'timeStamp' => $timeStamp,
            ];
            ksort($addData);
            $signStr = $this->config['app_key'].$data.$timeStamp;
        } else {
            $addData = [
                'appKey' => $this->config['app_key'],
                'data' => $data,
            ];
            ksort($addData);
            $signStr = $this->config['app_key'].$data;
        }

        $sign = strtoupper(hash_hmac('md5', $signStr, $this->config['sign_secret']));

        return array_merge($addData, ['sig' => $sign]);
    }

    /*
    添加默认参数
    */
    private function defaultQueryData($param)
    {
        $param['openChannel'] = $this->openChannel;
        //halt(json_encode($param, JSON_UNESCAPED_UNICODE));

        return $param;
    }
}
